/**
 * @author Kristian Mandrup
 * @date June 10, 2009
 * @version 0.1
 * 
 * m3gen :: JsonResolver
 */ 

/**
 * Public
 * Resolve the id of a jsonObj using the id rule defined in the active ruleSet
 * 
 * @param {Object} ruleSet
 * @param {Object} jsonObj
 * 
 * @return {string} id or null
 */
m3gen.Base.prototype.resolveId = function (ruleSet, jsonObj) {		
	var activeObj = jsonObj || this.getActiveObj();
	var activeFunctions = this.getActiveFunctionsByRuleset(ruleSet);	
	var selectId = activeFunctions.selectId;
	if (selectId) {
		var id = this.generateIdObj(selectId);
		return id;
		
	} else {
		return null;
		// throw m3gen.exception.MissingIdRule;				
	}
	
}

/**
 * Public
 * Resolve the unique id of a jsonObj using the id rule defined in the active ruleSet
 * 
 * @param {Object} ruleSet
 * @param {Object} jsonObj
 * 
 * @return {string} unique id or null
 */
m3gen.Base.prototype.resolveUniqueId = function (id) {		
	var uniqueId = this.getUniqueId(id);		
	return uniqueId;
}

/**
 * Public
 * Resolve the title of a jsonObj using the title rule defined in the active ruleSet
 * 
 * @param {Object} ruleSet
 * @param {Object} jsonObj
 * 
 * @return {Object} attributes hashset or null
 */
m3gen.Base.prototype.resolveAttributes = function (ruleSet, jsonObj) {	
	var activeFunctions = this.getActiveFunctionsByRuleset(ruleSet);
	var selectAttributes = activeFunctions.selectAttributes;
	if (selectAttributes) {
		return selectAttributes(jsonObj, this.getContext(this));
	} else {
		return null;
		// throw m3gen.exception.MissingAttributesRule;				
	}
}

/**
 * Public
 * Resolve the state of a jsonObj using the state rule defined in the active ruleSet
 * @param {Object} ruleSet
 * @param {Object} jsonObj
 */
m3gen.Base.prototype.resolveState = function (ruleSet, jsonObj) {
	var activeFunctions = this.getActiveFunctionsByRuleset(ruleSet);
	var selectState = activeFunctions.selectState;
	if (selectState) {
		var optionsState = this.getOptions('state');		
		var optionsId = this.getOptions('id');				
		return selectState(jsonObj, this.getContext(this), optionsState, optionsId);
	} else {
		return null;
		// throw m3gen.exception.MissingStateRule;
	}
}

/**
 * 
 * @param {Object} ruleSet
 * @param {Object} jsonObj
 */
m3gen.Base.prototype.resolveTitle = function(ruleSet, jsonObj){
	var activeFunctions = this.getActiveFunctionsByRuleset(ruleSet);
	var selectTitle = activeFunctions.selectTitle;
    if (this.isFunction(selectTitle)) {	
		var options = this.getOptions('title');		
		return selectTitle(jsonObj, this.getContext(this), options);
	} else {
		// use selectors and seperator to create title (rules)
		if (this.isValidObj(selectTitle) && this.isValidObj(selectTitle.selectors)) {
			return this.generateTitle(jsonObj, selectTitle);	
		}		
		// throw m3gen.exception.MissingStateRule;
	}
	return null;	
}

/**
 * 
 * @param {Object} ruleSet
 * @param {Object} jsonObj
 */
m3gen.Base.prototype.resolveIcon = function(ruleSet, jsonObj){
	var activeFunctions = this.getActiveFunctionsByRuleset(ruleSet);
	var selectIcon = activeFunctions.selectIcon;
    if (this.isFunction(selectIcon)) {	
		var options = this.getOptions('icon');		
		return selectIcon(jsonObj, this.getContext(this), options);
	} else {
		return null;
		// throw m3gen.exception.MissingStateRule;
	}	
}

/**
 * Generate an ID
 * @param {Object} jsonObj	- optional
 * @param {Object} selectId
 * 
 * @return {Object} {id: "...", unique_id: "..."}
 */
m3gen.Base.prototype.generateIdObj = function(selectId){
	// generate unique ID based on type and counter
	
    var idObj = this.generateIdObject();				
	
	// REFACTOR:
    // if an id function exists use this to find the node id
    if (this.isFunction(selectId)) {
		var options = this.getOptions('id');
		idObj = this.doSelect(selectId, 'Id', options);
		
    } else console.log('selectId not a function');
    return idObj;
}

/**
 * Generate a unique Id
 * @param jsonObj 	- optional
 * @param id 		- The id generated by generateId
 * id can be either a string identifier or an object
 * {id: '..', uniqueId: '..'}
 */
m3gen.Base.prototype.getUniqueId = function(id){	
	var activeObj = this.getActiveObj();
    var useUniqueId = this.getUseUniqueId();
    var uniqueId = id;
    if (useUniqueId && id.uniqueId) {
        uniqueId = id.uniqueId;
    }
    return uniqueId;
}

/**
 * 
 * @param {Object} jsonObj
 * @param {Object} titleObj
 */
m3gen.Base.prototype.generateTitle = function(jsonObj, titleObj) {
	var selectors = titleObj.selectors;
	var seperator = this.getObjDef(titleObj.seperator, ' ');
	var title = '';
	var that = this;
	selectors.forEach(function(selector) {		
		var str = that.resolveObjWithSelector(jsonObj, selector);
		title += (str + seperator);
	});
	return m3gen.util.trim(title);
	
}

